package ontology_ui;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import ontology_tools.OptionTraduction;
import ontology_tools.QueryBuilder;
import ontology_tools.SparqlProcessor;

/**
 * Clase que extiende de JPanel y que contiene los JComboBox con las opciones de
 * configuración de un ordenador, ademas de un JButton para iniciar la consulta.
 *
 * @author felipe & javi
 */
public class ChoisePane extends JPanel {

    private final static String PATHONTOLOGY = "file:./src/ontology_files/Computers_Ontology.owl";
    private DescriptionPane descriptionPane;
    private SparqlProcessor sparqlProcessor;
    private AbstractAction checkIfAllSelected;
    private AbstractAction showResult;
    private JButton acceptButton;
    private OptionTraduction optionTraductionBolsillo;
    private OptionTraduction optionTraductionUso;
    private OptionTraduction optionTraductionCapacidad;
    private JComboBox comboBoxBolsillo;
    private JComboBox comboBoxUso;
    private JComboBox comboBoxCapacidad;

    public ChoisePane(DescriptionPane panelDesc) {
        super();
        initializateOntology();
        initializateActions();
        initializateComboBox();

        this.descriptionPane = panelDesc;
        this.setBackground(new Color(192, 255, 62));
        this.setLayout(new FlowLayout());

        this.add(new JLabel("Bolsillo"));
        comboBoxBolsillo = new JComboBox(optionTraductionBolsillo.getOptions());
        comboBoxBolsillo.addActionListener(checkIfAllSelected);
        this.add(comboBoxBolsillo);

        this.add(new JLabel("¿Qué uso darás al ordenador?"));
        comboBoxUso = new JComboBox(optionTraductionUso.getOptions());
        comboBoxUso.addActionListener(checkIfAllSelected);
        this.add(comboBoxUso);

        this.add(new JLabel("¿Te importa más capacidad del disco duro o la velocidad?"));
        comboBoxCapacidad = new JComboBox(optionTraductionCapacidad.getOptions());
        comboBoxCapacidad.addActionListener(checkIfAllSelected);
        this.add(comboBoxCapacidad);

        acceptButton = new JButton("Generar Ordenador");
        acceptButton.addActionListener(showResult);
        acceptButton.setEnabled(false);
        this.add(acceptButton);
    }

    /**
     * Crea un Thread que cargará la ontología en memoria paralelamente mientras
     * se inicializan y cargan el resto de los componentes.
     */
    private void initializateOntology() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                sparqlProcessor = new SparqlProcessor(PATHONTOLOGY);
            }
        }).start();
    }

    /**
     * Inicializa las AbstractActions que se asociarán a los JComboBox y al
     * JButton.
     */
    private void initializateActions() {
        //Cuando están todos los JComboBox seleccionados se contruye la consulta, se ejecuta y se muestra.
        showResult = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                QueryBuilder queryBuilder = new QueryBuilder();
                queryBuilder.addToQuery(optionTraductionBolsillo.getTraduction(comboBoxBolsillo.getSelectedItem().toString()));
                queryBuilder.addToQuery(optionTraductionUso.getTraduction(comboBoxUso.getSelectedItem().toString()));
                queryBuilder.addToQuery(optionTraductionCapacidad.getTraduction(comboBoxCapacidad.getSelectedItem().toString()));
                String resultado = sparqlProcessor.executeQuery(queryBuilder.buildQuery());
                descriptionPane.setText(resultado);
            }
        };
        //Si no están todos los JComboBox seleccionados el JButon no es presionable.
        checkIfAllSelected = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (comboBoxBolsillo.getSelectedIndex() != 0 && comboBoxUso.getSelectedIndex() != 0 && comboBoxCapacidad.getSelectedIndex() != 0) {
                    acceptButton.setEnabled(true);
                } else {
                    acceptButton.setEnabled(false);
                }
            }
        };
    }

    /**
     * Inicializa las OptionTraduction con las opciones a mostrar y sus
     * respectivas traducciones en SPARQL (Trozos de la consulta).
     */
    private void initializateComboBox() {
        optionTraductionBolsillo = new OptionTraduction();
        optionTraductionBolsillo.putOptionTraduction("", "");
        optionTraductionBolsillo.putOptionTraduction("Ajustado",
                "?procesador rdfs:subClassOf ont:ProcesadorAMDAM2AM3 .\n"
                + "?placaBase rdfs:subClassOf ont:PlacaBaseAMD .\n"
                + "?r1 owl:someValuesFrom ont:EsEconomicamenteBarato .\n");
        optionTraductionBolsillo.putOptionTraduction("Flexible",
                "?procesador rdfs:subClassOf ont:ProcesadorIntel1155 .\n"
                + "?placaBase rdfs:subClassOf ont:PlacaBaseIntel1155 .\n"
                + "?r1 owl:someValuesFrom ont:EsEconomicamenteMedio .\n");
        optionTraductionBolsillo.putOptionTraduction("Indiferente",
                "?procesador rdfs:subClassOf ont:ProcesadorIntel2011 .\n"
                + "?placaBase rdfs:subClassOf ont:PlacaBaseIntel2011 .\n"
                + "?r1 owl:someValuesFrom ont:EsEconomicamenteCaro .\n");

        optionTraductionUso = new OptionTraduction();
        optionTraductionUso.putOptionTraduction("", "");
        optionTraductionUso.putOptionTraduction("Video Juegos",
                "?r2 owl:someValuesFrom ont:UsoDeComponentesParaJugar .\n");
        optionTraductionUso.putOptionTraduction("Programar",
                "?r2 owl:someValuesFrom ont:UsoDeComponentesParaProgramar .\n");
        optionTraductionUso.putOptionTraduction("Diseño Gráfico",
                "?r2 owl:someValuesFrom ont:UsoDeComponentesParaDisenoGrafico .\n");
        optionTraductionUso.putOptionTraduction("Ofimática",
                "?r2 owl:someValuesFrom ont:UsoDeComponentesParaOfimatica .\n");
        optionTraductionUso.putOptionTraduction("Uso Variado",
                "?r2 owl:someValuesFrom ont:UsoDeComponentesParaUsoVariado .\n");

        optionTraductionCapacidad = new OptionTraduction();
        optionTraductionCapacidad.putOptionTraduction("", "");
        optionTraductionCapacidad.putOptionTraduction("Capacidad",
                "?discoDuro rdfs:subClassOf ont:DiscoDuroCapacidad");
        optionTraductionCapacidad.putOptionTraduction("Velocidad",
                "?discoDuro rdfs:subClassOf ont:DiscoDuroVelocidad");
        optionTraductionCapacidad.putOptionTraduction("Equilibrado",
                "?discoDuro rdfs:subClassOf ont:DiscoDuroEquilibrado");
    }
}